// 文件名：priority_queue_task_scheduler.cpp
// 目的：基于优先队列的简单定时任务调度器，按“最早 readyAt 时间优先；同一时间按优先级高者先”的规则执行。
// 关键点：
//   - TaskCompare：自定义比较器，使 priority_queue 的 top() 为“最早 readyAt”，若相同则“priority 高”的任务；
//   - 调度循环：取队首任务，若未到时间则 sleep_until（此处用 sleep_for 剩余时长），到点后执行并弹出；
//   - steady_clock：避免系统时间跳变对调度的影响。
// 复杂度：
//   - 入队/出队：O(log N)；每个任务执行一次，总体 O(N log N) + 执行时间。
// 注意：
//   - 示例为单线程串行调度；并发/抢占等场景需更复杂的时间轮或多队列方案。

#include <chrono>
#include <functional>
#include <iostream>
#include <queue>
#include <string>
#include <thread>
#include <vector>

struct Task {
    int priority;
    std::chrono::steady_clock::time_point readyAt;
    std::string name;
    std::function<void()> fn;
};

struct TaskCompare {
    bool operator()(const Task& a, const Task& b) const noexcept {
        if (a.readyAt == b.readyAt) {
            return a.priority < b.priority; // readyAt 相同时优先级大的先执行
        }
        return a.readyAt > b.readyAt; // 时间早的优先执行
    }
};

int main() {
    using clock = std::chrono::steady_clock;
    std::priority_queue<Task, std::vector<Task>, TaskCompare> queue;

    auto now = clock::now();
    queue.push(Task{5, now + std::chrono::milliseconds(300), "Warmup", [] {
        std::cout << "  warming up...\n";
    }});
    queue.push(Task{10, now + std::chrono::milliseconds(100), "Init", [] {
        std::cout << "  initializing...\n";
    }});
    queue.push(Task{7, now + std::chrono::milliseconds(200), "LoadConfig", [] {
        std::cout << "  loading configuration...\n";
    }});

    while (!queue.empty()) {
        const Task& task = queue.top();
        auto sleepTime = task.readyAt - clock::now();
        if (sleepTime > std::chrono::milliseconds(0)) {
            std::this_thread::sleep_for(sleepTime);
        }
        std::cout << "Executing task: " << task.name
                  << " (priority " << task.priority << ")\n";
        task.fn();
        queue.pop();
    }

    return 0;
}